<template>
  <div class="bpmn-designer">
    <iframe
        class="w-full"
        :src="frameSrc"
        ref="frameRef"></iframe>
  </div>
</template>
<script setup name="BpmnDesigner">

import {getBpmnByModelKey} from "@/api/flowable/bpmn/modelInfo.js";
import { getToken } from "@/utils/auth";

const bpmnModeler = ref(null);
const {proxy} = getCurrentInstance();

const frameSrc = '/static/bpmn/designer/index.html';

const emit = defineEmits(['onLoadSuccess']);

const heightRef = ref(window.innerHeight);
const loading = ref(false);
const isDark = ref(false);

const props = defineProps({
  modelId: {
    type: String,
    default: '',
  },
  modelKey: {
    type: String,
    default: '',
  }
})

function init() {
  nextTick(() => {
    const iframe = proxy.$refs.frameRef;

    if (!iframe) return;
    const _frame = iframe;
    if (_frame.attachEvent) {
      _frame.attachEvent('onload', () => {
        try {
          emit('onLoadSuccess', _frame);
          handleLoadSuccess(_frame);
        } catch (e) {
          console.warn('未定义加载成功回调函数 - 【onLoadSuccess】');
        }
        // fitHeight();
      });
    } else {
      iframe.onload = () => {
        try {
          emit('onLoadSuccess', _frame);
          handleLoadSuccess(iframe);
        } catch (e) {
          console.warn('未定义加载成功回调函数 - 【onLoadSuccess】');
        }
        // fitHeight();
      };
    }
  });
}

const initCallback = (modeler) => {
  modeler.on('linting.completed', ({ issues }) => {
    issuesMap.value = issues;
    console.log(issues);
  });
};

// 将token发送给子iframe窗口
const handleLoadSuccess = (iframe) => {
  // 发送消息到子窗口
  const iframeContentWindow = iframe.contentWindow;
  bpmnModeler.value = iframeContentWindow.bpmnModeler;
  if (!iframeContentWindow.bpmnModeler) {
    proxy.$modal.msgError('设计器加载失败，原因：window下面bpmnModeler对象丢失！');
    return;
  }
  const msg = {
    type: 'userInfo',
    message: {
      token: getToken(),
    },
  };
  hideSaveBtn(iframe);
  changeDesignerTheme(iframe);
  initCallback(bpmnModeler.value);
  iframeContentWindow.postMessage(JSON.stringify(msg), '*');
  // 加载 xml
  loadModelXml();
};

// 加载xml
const loadModelXml = () => {
  if (!props.modelKey) {
    proxy.$modal.msgError('modelKey为空，加载失败！');
    return;
  }
  loading.value = true;
  getBpmnByModelKey({ modelKey: props.modelKey })
      .then((res) => {
        const {modelXml}  = res.data;
        if (bpmnModeler.value) {
          bpmnModeler.value
              .importXML(modelXml)
              .then(() => {
                bpmnModeler.value?.get('canvas').zoom('fit-viewport', {});
                loading.value = false;
              })
              .catch((e) => {
                proxy.$modal.msgError('加载设计器XML失败！');
                loading.value = false;
              });
        } else {
          loading.value = false;
        }
      })
      .catch((e) => {
        console.error(e);
        loading.value = false;
      });
};

const getBpmnXml = () => {
  return bpmnModeler.value.saveXML({ format: true });
};

const hideSaveBtn = (iframe) => {
  const iframeWindow = iframe.contentWindow;
  if (iframeWindow) {
    const btns = iframeWindow.document.querySelector('.bpmn-toolbar .arco-btn-group');
    if (btns) {
      if (btns.children) {
        if (btns.children[0].innerText === '保存') {
          btns.children[0].style.display = 'none';
        }
      }
    }
  }
};

const changeDesignerTheme = (iframe) => {
  // 获取当前框架主题
  const iframeWindow = iframe.contentWindow;
  if (iframeWindow) {
    if (isDark.value) {
      iframeWindow.document.body.setAttribute('arco-theme', 'dark');
    } else {
      iframeWindow.document.body.removeAttribute('arco-theme');
    }
  }
};

const getIssuesMap = () => {
  return issuesMap.value;
};

onMounted(() => {
  loading.value = true;
  init();
});

watch(() => props.modelKey, modelKey => {
  if (modelKey) {
    if(!bpmnModeler.value){
      init();
    }
    proxy.$nextTick(() => {
      loadModelXml();
    })
  }
},{ immediate: true });

defineExpose({
  getBpmnXml,
  getIssuesMap,
});
</script>
<style lang="scss" scoped>
.bpmn-designer {
  height: 100%;

  > iframe {
    width: 100%;
    height: 100%;
    border: 0;
    margin: 0;
    padding: 0;
  }
}
</style>
